package com.jackstraw.jack_base.mq.rocketmq.producer;

import com.jackstraw.jack_base.mq.rocketmq.bean.listener.ProducerTxService;
import com.jackstraw.jack_base.mq.rocketmq.bean.RocketMqMessage;
import com.jackstraw.jack_base.mq.common.entity.MQSendResult;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.TransactionSendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.messaging.Message;

public interface BaseProducer {

    /**
     * 获取RocketMQTemplate
     *
     * @return
     */
    RocketMQTemplate getRocketMQTemplate();

    /**
     * 获取DefaultMQProducer
     *
     * @return
     */
    DefaultMQProducer getDefaultMQProducer();


    /**
     * RocketMQTemplate 发送未序列化对象，如字符串，JSON等
     * 1.普通消息
     * 2.广播消息
     * 3.集群消息
     *
     * @param rocketMqMessage
     */
    MQSendResult send(RocketMqMessage<String> rocketMqMessage);

    /**
     * RocketMQTemplate 发送实体对象使用，可将实体对象转换为序列化流
     * 1.普通消息
     * 2.广播消息
     * 3.集群消息
     *
     * @param rocketMqMessage
     */
    <T> MQSendResult sendAndConvert(RocketMqMessage<T> rocketMqMessage, Class<T> tClass);

    /**
     * RocketMQTemplate 发送顺序消息
     *
     * @param rocketMqMessage
     */
    <T> MQSendResult sendAsyncOrderly(RocketMqMessage<T> rocketMqMessage, Class<T> tClass);

    /**
     * RocketMQTemplate 发送异步回调消息
     *
     * @param rocketMqMessage
     * @return
     */
    <T> MQSendResult<SendResult> sendSync(RocketMqMessage<T> rocketMqMessage, Class<T> tClass);

    /**
     * RocketMQTemplate 发送异步回调消息
     *
     * @param rocketMqMessage
     * @param tClass
     * @param <T>
     * @return
     */
    <T> MQSendResult<SendResult> sendSyncCollection(RocketMqMessage<T> rocketMqMessage, Class<T> tClass);

    /**
     * RocketMQTemplate 发送定时/延时消息
     *
     * @param rocketMqMessage
     * @return
     */
    <T> MQSendResult<SendResult> sendSyncDelayLevel(RocketMqMessage<T> rocketMqMessage, Class<T> tClass);


    /**
     * RocketMQTemplate 发送事务消息
     *
     * @param rocketMqMessage
     * @return
     */
    <T> MQSendResult<TransactionSendResult> sendMessageInTransaction(RocketMqMessage<T> rocketMqMessage, Class<T> tClass);

    /**
     * 构造Message
     *
     * @param <T>
     * @param rocketMqMessage
     * @param tClass
     * @return
     */
    <T> Object buildMessage(RocketMqMessage<T> rocketMqMessage, Class<T> tClass);

    /**
     * 构造Message
     *
     * @param rocketMqMessage
     * @return
     */
    Message<String> buildMessage(RocketMqMessage<String> rocketMqMessage);

    /**
     * 判断务消息是否包含回调服务类
     *
     * @return
     */
    default Boolean isHaveTransactionListener(RocketMqMessage rocketMqMessage) {
        return rocketMqMessage.getHeaders().containsKey(ProducerTxService.PRODUCER_TX_SERVICE_BEAN_NAME);
    }
}
